﻿// <copyright file="KingCleaner.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains the KingCleaner class</summary>

namespace Sqwarea.GameLogic
{
    using System;
    using Sqwarea.GameLogic.Extensions;
    using Sqwarea.Persistence;

    /// <summary>
    /// Class which enables batch to clean a king
    /// </summary>
    public class KingCleaner : IKingCleaner
    {
        /// <summary>
        /// The Game Provider
        /// </summary>
        private readonly IGameProvider _gameProvider;

        /// <summary>
        /// Initializes a new instance of the KingCleaner class.
        /// </summary>
        /// <param name="gameProvider">The GameProvider (provided by AutoFac)</param>
        public KingCleaner(IGameProvider gameProvider)
        {
            if (null == gameProvider)
            {
                throw new ArgumentNullException("gameProvider", "KingCleaner");
            }

            _gameProvider = gameProvider;
        }

        /// <summary>
        /// Clean a king :
        /// * if neutral <see cref="CleanNeutralKing"/>
        /// * otherwise : just clean incoming/ongoing attacks
        /// </summary>
        /// <param name="kingId">The id of the king to clean</param>
        public void CleanKing(long kingId)
        {
            var king = _gameProvider.GetKingById(kingId);

            if (king.IsNeutral())
            {
                CleanNeutralKing(king);
                return;
            }

            _gameProvider.ClearElapsedAttacks(new[] { kingId });
        }

        /// <summary>
        /// Clean a neutral king :
        /// * ensure that old king square has no king and is neutral (except if it has a new owner)
        /// * remove all incoming/ongoing attacks (but not in the attack queue because it's not possible)
        /// WARNING : Do not change king Id because of attack in attack queue and square with this king id.
        /// </summary>
        /// <param name="king">The king to clean</param>
        protected void CleanNeutralKing(King king)
        {
            var sq = _gameProvider.GetSquareByPosition(king.Position);
            King k1 = king;
            _gameProvider.UpdateSquare(
                sq.Position,
                s =>
                {
                    if (s.HasKing && (s.KingId == k1.Id) && (k1.OpenId == null))
                    {
                        s.HasKing = false;
                        s.KingId = King.NeutralKingId;
                    }

                    return s;
                });
        }
    }
}
